package server

import (
	"cgs-server/helper"
	"cgs-server/pkg/set"
	"context"
	"go.mongodb.org/mongo-driver/bson"
	"go.mongodb.org/mongo-driver/bson/primitive"
	"net/http"
	"strings"
)

var urlSet = set.NewSetFormSlice([]interface{}{
	"/api/Cgs/Portal/Visual/Detail",
	"/api/Cgs/Portal/CgsMap/detail",
	"/api/Cgs/Worksheet/GetWorksheetInfo",
	"/api/Cgs/Worksheet/GetWorksheetInfoById",
	"/api/Cgs/Worksheet/GetFilterData",
})

func AccessTokenMiddleware(w http.ResponseWriter, r *http.Request, next http.HandlerFunc) {

	//if !urlSet.Contains(r.URL.Path) {
	//	next(w, r)
	//	return
	//}
	_, ok := apiAuthorities2[r.URL.Path]
	if !ok {
		// path is not registered.
		Logger.Errorf("%v is not registered", r.URL.Path)
		writeNotAllowed(w)
		return
	}

	// api needs no authority
	accessToken := ""
	if len(r.Header) > 0 {
		for k, v := range r.Header {
			if k == "Access-Token" {
				accessToken = v[0]
			}
		}
	}
	if accessToken == "" {
		next(w, r)
		return
	}

	db, err := Mongo()
	if err != nil {
		Fail(err.Error())
		return
	}
	decryptBase62 := helper.DecryptBase62(accessToken)
	split := strings.Split(decryptBase62, "&")
	if len(split) != 3 {
		next(w, r)
		return
	}

	appKey := split[0]
	appSecret := split[1]
	timestamp := split[2]

	filter := bson.M{
		"AppKey": appKey,
	}
	doc := AppKey{}
	find, _ := db.FindOne(CgsAppKeyCollectionName, filter, &doc)
	if !find {
		next(w, r)
		return
	} else {

		if doc.AuthType == "0" {
			// 密钥未启用
			next(w, r)
			return
		}

		if appSecret != doc.AppSecret || timestamp != doc.Timestamp {
			next(w, r)
			return
		}

		//if len(doc.WhiteList) > 0 {
		//	helper.EnableCrossDomain(w, r, doc.WhiteList...)
		//}

		ctx := context.WithValue(r.Context(), "userID", doc.UserID)
		ctx = context.WithValue(ctx, "authType", doc.AuthType)
		r = r.WithContext(ctx)
		next(w, r)
		return
	}
}

type AppKey struct {
	ID        primitive.ObjectID
	AppKey    string
	AppSecret string
	Sign      string
	AuthType  string //0 未启用  1//只读  2//读写
	Remark    string
	Timestamp string
	UserID    string
	// WhiteList 访问白名单
	WhiteList []string
}
